/*!
 Temelia - Graph Edge implementation source file.

 Copyright (C) 2008, 2009 Ceata (http://ceata.org/proiecte/temelia).

 @author Dascalu Laurentiu

 This program is free software; you can redistribute it and
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 3
 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#include "include/edge.h"
#include <stdio.h>
#include <stdlib.h>

DECLSPEC char DFS_edge_Types[4][10] =
{ "tree", "forward", "back", "cross" };

DECLSPEC char BFS_edge_Types[10][5] =
{ "tree", "back", "cross" };

struct _edge_t
{
	/*! vertices */
	vertex_t vertex1, vertex2;

	/*! cost */
	double cost;

	/*! label */
	char *label;

	/*! type */
	int type;

	/*! user's key */
	void *key;
};

edge_t edge_new(vertex_t vertex1, vertex_t vertex2, double cost, char *label,
		void *key)
{
	edge_t edge;

	edge = (struct _edge_t *) _new(sizeof(struct _edge_t));

	edge->label = label;
	edge->vertex1 = vertex1;
	edge->vertex2 = vertex2;
	edge->cost = cost;
	edge->key = key;
	edge->type = 0;

	return edge;
}

void edge_delete(edge_t edge)
{
	_ASSERT(edge, ==, NULL, NULL_POINTER,);

	edge->cost = 0;
	edge->label = NULL;

	edge->vertex1 = edge->vertex2 = NULL;

	edge->key = NULL;

	_delete(edge);
}

vertex_t edge_get_vertex1(edge_t edge)
{
	_ASSERT(edge, ==, NULL, NULL_POINTER, NULL);

	return edge->vertex1;
}

vertex_t edge_get_vertex2(edge_t edge)
{
	_ASSERT(edge, ==, NULL, NULL_POINTER, NULL);

	return edge->vertex2;
}

vertex_t edge_complementary_vertex(edge_t edge, vertex_t vertex)
{
	_ASSERT(edge, ==, NULL, NULL_POINTER, NULL);

	if (edge->vertex1 == vertex)
		return edge->vertex2;
	else if (edge->vertex2 == vertex)
		return edge->vertex1;

	return NULL;
}

double edge_get_cost(edge_t edge)
{
	_ASSERT(edge, ==, NULL, NULL_POINTER, TEMELIA_INFINITY);

	return edge->cost;
}

int edge_get_type(edge_t edge)
{
	_ASSERT(edge, == , NULL, NULL_POINTER, -1);

	return edge->type;
}

void *edge_get_key(edge_t edge)
{
	_ASSERT(edge, ==, NULL, NULL_POINTER, NULL);

	return edge->key;
}

char *edge_get_label(edge_t edge)
{
	_ASSERT(edge, ==, NULL, NULL_POINTER, NULL);

	return edge->label;
}

void edge_set_vertex1(edge_t edge, vertex_t vertex)
{
	_ASSERT(edge, ==, NULL, NULL_POINTER,);

	edge->vertex1 = vertex;
}

void edge_set_vertex2(edge_t edge, vertex_t vertex)
{
	_ASSERT(edge, ==, NULL, NULL_POINTER,);

	edge->vertex2 = vertex;
}

void edge_set_cost(edge_t edge, double cost)
{
	_ASSERT(edge, ==, NULL, NULL_POINTER,);

	edge->cost = cost;
}

void edge_set_type(edge_t edge, int type)
{
	_ASSERT(edge, ==, NULL, NULL_POINTER,);

	edge->type = type;
}

void edge_set_key(edge_t edge, void *key)
{
	_ASSERT(edge, ==, NULL, NULL_POINTER,);

	edge->key = key;
}

void edge_set_label(edge_t edge, char *label)
{
	_ASSERT(edge, ==, NULL, NULL_POINTER,);

	edge->label = label;
}

void edge_debug(edge_t edge, void *stream)
{
	_ASSERT(edge, ==, NULL, NULL_POINTER,);

	if (stream == NULL)
		stream = stdout;

	fprintf(stream,
			"vertex1 %u, vertex2 %u, label %s, cost %lf, type %d, key %p\n",
			vertex_get_identifier(edge->vertex1), vertex_get_identifier(
					edge->vertex2), edge->label, edge->cost, (int) edge->type,
			edge->key);
}

void edge_switch_vertices(edge_t edge)
{
	vertex_t aux;

	_ASSERT(edge, ==, NULL, NULL_POINTER,);

	aux = edge->vertex1;
	edge->vertex1 = edge->vertex2;
	edge->vertex2 = aux;
}
